| ![]() |
HttpListener has a built-in support for authentication against Windows users and Active Dicectory users. To activate IWA you must set HttpListener.AuthenticationSchemes property to Ntlm. The logged in user than will be available via HttpListenerContext.User property.
HttpListener listener = new HttpListener();
listener.Prefixes.Add(uriPrefix);
listener.AuthenticationSchemes = AuthenticationSchemes.Ntlm;
listener.Start();
while (true)
{
WDEngine engine = new
WDEngine();
HttpListenerContext context = listener.GetContext();
WDRequest request = new
WDRequest(context.Request, context.User);
WDResponse response = new
WDResponse(context.Response);
engine.Run(request,
response);
if (response.StatusCode == 401)
{
byte[] message = new UTF8Encoding().GetBytes("Access
denied");
context.Response.OutputStream.Write(message, 0, message.Length);
}
try
{
context.Response.Close();
}
catch
{
// client closed connection before the content was sent
}
}
public WebDAVResponse
WriteToStream(Stream output, long startIndex, long
count)
{
if (request.User.Identity.Name.ToLower() != "domain\\user1")
return new AccessDeniedResponse();
// sets 401 status code
...
return new OkResponse();
}
HttpListener does not attach WWW-Authenticate header, so you must set it yourself to display login dialog.
Cofiguring Impersonation
To run your code on behalf of the Windows user account accessing the server configure IWA and call WindowsIdentity.Impersonate() method:
HttpListener listener = new HttpListener();
listener.Prefixes.Add(uriPrefix);
listener.AuthenticationSchemes = AuthenticationSchemes.Ntlm;
listener.Start();
...
HttpListenerContext context = listener.GetContext();
...
WindowsIdentity identity = (WindowsIdentity)context.User.Identity;
WindowsImpersonationContext wic = identity.Impersonate();
// Run code on behalf of the client
engine.Run(request, response);
wic.Undo();
HttpListener Kerberos Authentication
To access remote servers you may need a delegation level of impersonation. To setup delegation your server must use Kerberos authentication. By default, Active Directory allows only the Network Service and Local System accounts to use Kerberos. Usually to run your HttpListener WebDAV server under one of this accounts you will have to create a Windows Service.
To setup HttpListener for Kerberos authentication set HttpListener.AuthenticationSchemes property to IntegratedWindowsAuthentication:listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
While HttpListener has basic authentication support it does not authenticate against windows accounts and domain accounts. HttpListener will simply extract and decode username and password for you from HTTP headers. You can read user credentials as properties of HttpListenerBasicIdentity class and authenticate against your custom users store.
HttpListener listener = new HttpListener();
listener.Prefixes.Add(uriPrefix);
listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
listener.Start();
while (true)
{
WDEngine engine = new
WDEngine();
HttpListenerContext context = listener.GetContext();
HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;
if ((identity.Name == "User1")
&& (identity.Password == "pwd"))
{
WDRequest request = new
WDRequest(context.Request, context.User);
WDResponse response = new
WDResponse(context.Response);
engine.Run(request,
response);
}
else
{
context.Response.StatusCode = 401;
}
if (context.Response.StatusCode == 401)
{
context.Response.AddHeader("WWW-Authenticate",
"Basic Realm=\"My WebDAV Server\"");
// show login dialog
byte[] message = new UTF8Encoding().GetBytes("Access
denied");
context.Response.ContentLength64 = message.Length;
context.Response.OutputStream.Write(message, 0, message.Length);
}
try
{
context.Response.Close();
}
catch
{
// client
closed connection before the content was sent
}
}
public WebDAVResponse CreateFolder(string name)
{
if (request.User.Identity.Name != "User1")
return new AccessDeniedResponse();
...
return new CreatedResponse();
}
HttpListener does not send WWW-Authenticate header, so you must set it yourself to display login dialog.
To configure SSL for HttpListener you can use following tools: